#!/usr/bin/env python
""" Parameter Parser for command line interface.

AnyProg  arg1 arg2 aoption=10 boption=[1,2,3,4] +doption -coption

+option is same as option=True
-option is same as option=False

if ambiguous the option names can be shortend.

AnyProg  arg1 arg2 a=10 b=[1,2,3,4] +d -c

Configuration with array
optnames=[
        { 'name':'outfile_name'         ,'type':str,  'default':'out.hex','comment':'Name of the output file.' },
        { 'name':'infile_name'          ,'type':str,  'default':'in.hex','comment':'Name of the input file.'},
        { 'name':'address'              ,'type':int,  'default':None,     'comment':'Address.'}]

"""
__author__      = "Michael J. Hohmann"
__copyright__   = "Copyright 2017, Linde Material Handling GmbH"
__versio__      = "0.0.1"
__email__       = "michael.hohmann@lind-mh.de"
__status__      = "Prototype"
__date__        = "2017-02-20"



class argopt:
    optnames=[]
    current_args=[]
    current_opots={}
    
    def __init__(self, option_list):
        self.optnames=option_list
        self.add_default()

    def find_optname( self, text ):
        rv=[]
        text=text.lower()
        for key in self.optnames:
            if key['name'].lower().startswith(text):
                rv.append(key['name'])
        return rv
            

    def merge_cfg_file(self, filename ):
        g={}
        l={}
        exec(open(filename).read(),g,l)
        
        for item in self.optnames:
            if item['name'] in l.keys():
                self.current_opots[item['name']] = l[item['name']]

    def add_default(self):
        for item in self.optnames:
            #if item['default']!=None:
                self.current_opots[item['name']]=item['default']
                
    def parameter(self, argv):
        unknown=[]
        for pos in range(1,len(argv)):
            if argv[pos][0]=='+':
                items=(argv[pos][1:],'True')
            else:
                if argv[pos][0]=='-':
                    items=(argv[pos][1:],'False')
                else:
                    items=argv[pos].split('=')
            if len(items)==1:# is an argument 
                self.current_args.append(items[0])        
            else:
                names=self.find_optname(items[0])
                if len(names)==0:
                    unknown.append( (items[0],()))
                else:
                    if len(names)>1:
                        unknown.append( (items[0],names) )
                    else:
                        #add option to dict
                        try:
                            new_value =eval(items[1])
                        except:
                            new_value =items[1]
                        #if names[0] in self.current_opots: #already set - overwrite
                        #    unknown.append( (items[0],names,new_value) )
                        self.current_opots[names[0]]=new_value
        return unknown,self.current_args,self.current_opots


def help_text(self):
    rv=''
    for item in self.optnames:
        rv+='  - '+item['name']+'\n'
        rv+='    '+item['comment']
        

def parse( argv, option_names ):
    p=argopt(option_names)
    return p.parameter( argv )
        
def print_unknown( unknownlist,prefix="",appendix=""  ):
    for item in unknownlist:
        if len(item[1])==0:
            print( prefix,'Option "'+item[0]+'" is unknown.'+appendix)
        else:
            print( prefix,'Option "'+item[0]+'" is ambiguous.' )
            print( 'Could be one of the following:'+str(item[1]))
            print( appendix)
        
        

        
if __name__=="__main__":

    import sys
        
    #data=[ "segments","inputfile","outputfile","outformat"]
    
    data=[
            { 'name':'outfile_name'         ,'type':type(str),  'default':'out.hex','comment':'Name of the output file.' },
            { 'name':'infile_name'          ,'type':type(str),  'default':'out.hex','comment':'Name of the input file.'},
            { 'name':'address'              ,'type':type(int),  'default':None,     'comment':'Address of BIS-Address.'},
            { 'name':'segments'             ,'type':type(list), 'default':None,     'comment':'List of segement addresses.'},
            { 'name':'version'              ,'type':type(int),  'default':0x1,      'comment':'Version number of the BIS.'},
            { 'name':'build_time'           ,'type':type(int),  'default':int(time.time()), 'comment':'Build time stamp.'},
            { 'name':'diagnostic_version'   ,'type':type(int),  'default':0x1,      'comment':'Diagnostic version number.'},
            { 'name':'reserved'             ,'type':type(int),  'default':0x0,      'comment':'Value of the reserved field. '},
       ]
    
    
    
    # name, type default value, comment
    #xdata=[ ["segments",type(1),None,"Segments to be filled",]
    
    #,"inputfile","outputfile","outformat"]


    unknown,args,opts= parse( sys.argv, data )
    
    print_unknown(unknown,"Warning - ","Option will be ignored.")
    
    
    
    
    if len(args)==0:
        print( "you need at least one argument")
    
    print( str(args))
    print( str(opts))
        
    